# Copyright (c) 2022, hzmes and contributors
# For license information, please see license.txt

import frappe
from frappe.model.document import Document
from frappe.utils import cint, cstr, flt, formatdate
from srm.srm.doctype.srm_server_config.srm_server_config import get_po_price_by_poentryid, sync_to_k3cloud_receiveBill, sync_to_k3cloud_plan_of_answer_from_delivery

class SRMPurchaseDelivery(Document):
	def before_save(self):
		self.supplier_name = frappe.db.get_value('SRM Supplier', self.supplier_number, 'supplier_name')

	def after_insert(self):
		items = self.items
		for i in items:
			if i.source_billtype == 'SRM Purchase Order':
				if frappe.db.exists('SRM Purchase Order Sub', i.source_billname):
					old_relation_qty = frappe.db.get_value('SRM Purchase Order Sub', i.source_billname, 'relation_qty')
					old_relation_qty2 = flt(old_relation_qty) if old_relation_qty else 0
					frappe.db.set_value('SRM Purchase Order Sub', i.source_billname, 'relation_qty', flt(old_relation_qty2) + flt(i.real_qty))

			if i.source_billtype == 'SRM Supply Plan Of Supplier':
				if frappe.db.exists('SRM Supply Plan Of Supplier OrderItem', i.source_billname):
					old_relation_qty = frappe.db.get_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'relation_qty')
					old_relation_qty2 = flt(old_relation_qty) if old_relation_qty else 0
					frappe.db.set_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'relation_qty', flt(old_relation_qty2) + flt(i.real_qty))

	def on_submit(self):
		items = self.items
		for i in items:
			if i.source_billtype == 'SRM Purchase Order':
				if frappe.db.exists('SRM Purchase Order Sub', i.source_billname):
					old_delivery_qty = frappe.db.get_value('SRM Purchase Order Sub', i.source_billname, 'delivery_qty')
					old_delivery_qty2 = flt(old_delivery_qty) if old_delivery_qty else 0
					frappe.db.set_value('SRM Purchase Order Sub', i.source_billname, 'delivery_qty', flt(old_delivery_qty2) + flt(i.real_qty))
			if i.source_billtype == 'SRM Supply Plan Of Supplier':
				if frappe.db.exists('SRM Supply Plan Of Supplier OrderItem', i.source_billname):
					old_delivery_qty = frappe.db.get_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'delivery_qty')
					old_delivery_qty2 = flt(old_delivery_qty) if old_delivery_qty else 0
					frappe.db.set_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'delivery_qty', flt(old_delivery_qty2) + flt(i.real_qty))
			
	def on_cancel(self):
		items = self.items
		for i in items:
			if i.source_billtype == 'SRM Purchase Order':
				if frappe.db.exists('SRM Purchase Order Sub', i.source_billname):
					old_delivery_qty = frappe.db.get_value('SRM Purchase Order Sub', i.source_billname, 'delivery_qty')
					old_delivery_qty2 = flt(old_delivery_qty) if old_delivery_qty else 0
					frappe.db.set_value('SRM Purchase Order Sub', i.source_billname, 'delivery_qty', flt(old_delivery_qty2) - flt(i.real_qty))
					old_relation_qty = frappe.db.get_value('SRM Purchase Order Sub', i.source_billname, 'relation_qty')
					old_relation_qty2 = flt(old_relation_qty) if old_relation_qty else 0
					frappe.db.set_value('SRM Purchase Order Sub', i.source_billname, 'relation_qty', flt(old_relation_qty2) - flt(i.real_qty))
			if i.source_billtype == 'SRM Supply Plan Of Supplier':
				if frappe.db.exists('SRM Supply Plan Of Supplier OrderItem', i.source_billname):
					old_delivery_qty = frappe.db.get_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'delivery_qty')
					old_delivery_qty2 = flt(old_delivery_qty) if old_delivery_qty else 0
					frappe.db.set_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'delivery_qty', flt(old_delivery_qty2) - flt(i.real_qty))
					old_relation_qty = frappe.db.get_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'relation_qty')
					old_relation_qty2 = flt(old_relation_qty) if old_relation_qty else 0
					frappe.db.set_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'relation_qty', flt(old_relation_qty2) - flt(i.real_qty))
			
	def after_delete(self):
		# 如果是已经cancel的记录删除
		if self.docstatus == 2:
			pass
		else:
			items = self.items
			for i in items:
				if i.source_billtype == 'SRM Purchase Order':
					if frappe.db.exists('SRM Purchase Order Sub', i.source_billname):
						old_relation_qty = frappe.db.get_value('SRM Purchase Order Sub', i.source_billname, 'relation_qty')
						old_relation_qty2 = flt(old_relation_qty) if old_relation_qty else 0
						frappe.db.set_value('SRM Purchase Order Sub', i.source_billname, 'relation_qty', flt(old_relation_qty2) - flt(i.real_qty))
				if i.source_billtype == 'SRM Supply Plan Of Supplier':
					if frappe.db.exists('SRM Supply Plan Of Supplier OrderItem', i.source_billname):
						old_relation_qty = frappe.db.get_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'relation_qty')
						old_relation_qty2 = flt(old_relation_qty) if old_relation_qty else 0
						frappe.db.set_value('SRM Supply Plan Of Supplier OrderItem', i.source_billname, 'relation_qty', flt(old_relation_qty2) - flt(i.real_qty))
				
	# 从采购PO上查询: source_billtype必须是SRM Purchase Order
	@frappe.whitelist()
	def get_data_from_po(self, supplier_number):
		sql = f"select t2.name as source_billname, t2.material_number, t2.material_name, t2.material_model, (t2.qty - IFNULL(t2.relation_qty, 0)) as qty, t2.po_entryid, t1.erp_billno as po_billno, t2.request_date, t2.uom, t2.price, t2.tax_rate, t2.tax_price, 'SRM Purchase Order' as source_billtype from `tabSRM Purchase Order` t1 join `tabSRM Purchase Order Sub` t2 on t1.name = t2.parent and t1.srm_supplier = '{supplier_number}' and t1.doc_closed = 'A' and (t2.qty - IFNULL(t2.relation_qty, 0)) > 0 order by t2.material_number, t2.request_date;"
		result = frappe.db.sql(sql,as_dict=1)
		return result

	# 从回复交期中查询: source_billtype必须是SRM Supply Plan Of Supplier
	@frappe.whitelist()
	def get_data_from_plan(self, supplier_number):
		# sql = f"select t2.name as source_billname, t2.material_number, t2.material_name, t2.material_model, (t2.assign_qty - IFNULL(t2.relation_qty, 0)) as qty, (t2.order_qty - IFNULL(t2.stock_qty, 0) - IFNULL(t2.inspect_qty, 0) ) as fsurplusqty, t2.po_entryid, t2.po_billno, t2.need_date as request_date, t2.uom_name as uom, t2.mpq, t2.lt, 'SRM Supply Plan Of Supplier' as source_billtype from `tabSRM Supply Plan Of Supplier` t1 join `tabSRM Supply Plan Of Supplier OrderItem` t2 on t1.name = t2.parent and t1.supplier_number = '{supplier_number}' and t1.is_answer = 1 and t1.is_last = 1 and (t2.assign_qty - IFNULL(t2.relation_qty, 0)) >0 order by t2.material_number, t2.need_date;"
		# 2023-04-08: 因为用relation_qty容易在送货单保存后再删除行记录错乱,改为用提交后的数量扣减
		sql = f"select t2.name as source_billname, t2.material_number, t2.material_name, t2.material_model, (t2.assign_qty - IFNULL(t2.delivery_qty, 0)) as qty, (t2.order_qty - IFNULL(t2.stock_qty, 0) - IFNULL(t2.inspect_qty, 0) ) as fsurplusqty, t2.po_entryid, t2.po_billno, t2.need_date as request_date, t2.uom_name as uom, t2.mpq, t2.lt, 'SRM Supply Plan Of Supplier' as source_billtype from `tabSRM Supply Plan Of Supplier` t1 join `tabSRM Supply Plan Of Supplier OrderItem` t2 on t1.name = t2.parent and t1.supplier_number = '{supplier_number}' and t1.is_answer = 1 and t1.is_last = 1 and (t2.assign_qty - IFNULL(t2.delivery_qty, 0)) >0 order by t2.material_number, t2.need_date;"
		result = frappe.db.sql(sql,as_dict=1)
		return result

	# 把送货明细与API返回的相关单价再组合出子表,以便于写入收料通知单
	@frappe.whitelist()
	def method_1(self):
		# 给一个不存在的分录ID,以确保在转换为tuple时不会只有一个元素
		poentryids = [-111]
		for row in self.items:
			poentryids.append(row.po_entryid)
		if len(poentryids) >1:
			ids = set(poentryids)
			r = get_po_price_by_poentryid(ids)
			return r

	# 把送货明细汇总便于打印取数
	@frappe.whitelist()
	def get_items_groupby(self):
		sql = f"""
		select material_number, material_name, material_model, uom, sum(IFNULL(real_qty, 0)) as real_qty, sum(IFNULL(spares_qty, 0)) as spares_qty, po_billno 
			from `tabSRM Purchase Delivery Sub` where parent = '{self.name}' 
			group by material_number, material_name, material_model, uom, po_billno; 
		"""
		return frappe.db.sql(sql, as_dict=True)

	@frappe.whitelist()
	def doc_sync_to_k3cloud_receiveBill(self):
		pass
		# 2023-05-11构建写入收料通知单的JSON串: 1.构建DetailEntity子串; 2.构建model; 3.构建post_options; 4.dumps并且构建post_data
		DetailEntity = []
		for i in self.items:
			DetailEntity.append({
				"FMaterialId": {"FNumber": i.material_number},
				"FUnitID": {"FNumber": i.uom},
				# 交货数量
				"FACTRECEIVEQTY": i.real_qty,
				"FPriceUnitID": {"FNumber": i.uom},
				"FStockUnitID": {"FNumber": i.uom},
				"FSRCBIZUNITID": {"FNumber": i.uom},
				# 批号
				"FLot": {"FNumber": ""},
				# 源单类型
				"FSrcFormId": "PUR_PurchaseOrder",
				"FPrice": 0, #price,
				"FEntryTaxRate": 0, #tax_rate,
				"FTaxPrice": 0, #tax_price,
				"FTaxNetPrice": 0, #price,
				"FGiveAway": "0",  #赠品
				# 收料仓库
				"FStockID": {"FNumber": ""},
				"FPRICEQTY": i.real_qty,
				# 库存单位数量
				"FSTOCKQTY": i.real_qty,
				# 货主类型
				"FOWNERTYPEID": "BD_Supplier",
				# 货主
				"FOWNERID": {"FNumber": self.supplier_name},
				# 九联自定义字段-提前收料
				"F_JLKJ_TQSL": true,
				# 源单类型
				"FSRCBILLTYPEID": "PUR_PurchaseOrder",
				# 源单单号
				"FSRCBillNo": i.po_billno,
				# 源单内码
				"FSrcId": i.po_billid,
				# 源单分录内码
				"FSrcEntryId": i.po_entryid,
				# 订单单号
				"FOrderBillNo": i.po_billno,
				# 采购订单分录内码
				"FPOORDERENTRYID": i.po_entryid,
				"FDetailEntity_Link": [{
					# 转换规则
					"FDetailEntity_Link_FRuleId": "PUR_PurchaseOrder-PUR_ReceiveBill",
					# 源单表
					"FDetailEntity_Link_FSTableName": "T_PUR_POOrderEntry",
					# 源单内码
					"FDetailEntity_Link_FSBillId": i.po_billid,
					# 源单分录内码
					"FDetailEntity_Link_FSId": i.po_entryid,
					# 修改携带量
					"FDetailEntity_Link_FBaseUnitQty": i.real_qty,
					# 修改携带量
					"FDetailEntity_Link_FStockBaseQty": i.real_qty
				}]
			})
			model = {
                # 单据类型: 标准收料单
                "FBillTypeID": {"FNumber": "SLD01_SYS"},
                # 业务类型: 标准采购
                "FBusinessType": "CG",
                "FDate": self.date,
                # "FCreatorId": {"FUserID": userid},
                "FStockOrgId": {"FNumber": "UM01"},
                "FPurchaseOrgId": {"FNumber": "UM01"},
                # 供应商
                "FSupplierId": {"FNumber": self.supplier_number},
                # 货主
                "FOwnerTypeIdHead": "BD_Supplier",
                "FOwnerIdHead": {"FNumber": self.supplier_number},
                "FinanceEntity": {"FSettleOrgId": {"FNumber": "UM01"}, "FSettleCurrId": {"FNumber": "PRE001"},"FPriceListId": {"FNumber": ""},"FPriceTimePoint": "1"},
                "FDetailEntity": DetailEntity
            }
		sync_to_k3cloud_receiveBill(model)
		return model
        
	# 2023-11-13: 是来源于采购订单的送货单, 即是采购员创建的送货单, 要写入K3Cloud[供应商协同采购回复(九联)] 
	@frappe.whitelist()
	def sync_to_erp_answerdetail(self):
		entry_list = []
		d = formatdate(self.date)
		for i in self.items:
			ls = []
			if i.real_qty:
				ls.append(d)
				ls.append(i.real_qty)
				ls.append(i.po_entryid)
				entry_list.append(ls)
		if len(entry_list)>0:
			r = sync_to_k3cloud_plan_of_answer_from_delivery(entry_list)
			return r
		else:
			frappe.throw("请确认送货明细的实发数量和PO行内码是否有效!")